<template>
  <div>
    <ul class="file-list">
      <li
        v-for="(item, index) in uploadFile"
        style="display: flex;align-items: center;justify-content: center;margin-right: 10px;margin-top: 10px;"
        :style="{ 'width': `${windowWidth}px`, 'height': `${windowHeight}px`, 'line-height': `${windowHeight}px` }"
      >
        <div
          v-if="item.type === 1" class="demo-upload-list"
          :style="{ 'width': `${windowWidth}px`, 'height': `${windowHeight}px`, 'line-height': `${windowHeight}px` }"
        >
          <img style="width: 100%;height:100%;object-fit:cover" :src="item.url" alt="">
          <div class="demo-upload-list-cover" style="width: 100%;height:100%">
            <Icon type="ios-eye-outline" @click.native="handleView(item)" />
            <Icon v-if="ifEdit && !isDisabled" type="ios-trash-outline" @click.native="handleRemove(index, item)" />
          </div>
        </div>
        <div
          v-if="item.type === 2"
          style="display: flex;align-items: center;justify-content: center;position: relative"
          :style="{ 'width': `${windowWidth}px`, 'height': `${windowHeight}px`, 'line-height': `${windowHeight}px` }"
        >
          <audio style="width: 100%;height:100%" :src="item.url" controls="controls" />
          <Icon
            v-if="ifEdit && !isDisabled" type="ios-trash" size="20" style="color: red;cursor: pointer;position: absolute;right: 0;top: 0;"
            @click.native="handleRemove(index, item)"
          />
        </div>
        <div
          v-if="item.type === 3"
          style="display: flex;align-items: center;justify-content: center;position: relative"
          :style="{ 'width': `${windowWidth}px`, 'height': `${windowHeight}px`, 'line-height': `${windowHeight}px` }"
        >
          <video style="width: 100%;height:100%" :src="item.url" controls="controls" />
          <Icon
            v-if="ifEdit && !isDisabled" type="ios-trash" size="20" style="color: red;cursor: pointer;position: absolute;right: 0;top: 0;"
            @click.native="handleRemove(index, item)"
          />
        </div>
      </li>
      <li v-if="uploadFile.length < maxLength && ifEdit" class="file-list_upload" style="margin-top: 10px;">
        <Upload
          ref="uploadMediaRef"
          :headers="headers"
          :multiple="multiple"
          :show-upload-list="showUploadList"
          :format="format"
          :accept="accept"
          :max-size="maxSize"
          :data="data"
          :disabled="isDisabled"
          :before-upload="handleBeforeUpload"
          :on-success="handleUploadSuccess"
          :on-exceeded-size="handleMaxSize"
          :on-format-error="handleFormatError"
          :on-error="handleUploadError"
          type="select"
          style="display: inline-block;" :style="{ width: `${windowWidth}px` }" :action="uploadUrl"
        >
          <div
            style="border: 1px dashed #dcdee2;border-radius: 6px"
            :style="{ 'width': `${windowWidth}px`, 'height': `${windowHeight}px`, 'line-height': `${windowHeight}px` }"
          >
            <Icon :type="computeIcon" size="30" />
          </div>
        </Upload>
      </li>
    </ul>
  </div>
</template>

<script>
import Viewer from 'viewerjs'
import 'viewerjs/dist/viewer.css'
import Recorder from '../../views/family-school/evaluation/component/recorder.vue'

export default {
  name: 'MediaUpload',
  components: { Recorder },
  props: {
    computeIcon: {
      default: 'ios-add'
    },
    multiple: {
      default: false
    },
    accept: {
      default: ''
    },
    showUploadList: {
      default: false
    },
    windowWidth: {
      default: 58
    },
    windowHeight: {
      default: 58
    },
    defaultFileList: {
      default: () => {
        return []
      }
    },
    ifEdit: {
      default: true
    },
    maxLength: {
      default: 1
    },
    type: String,
    maxSize: {
      default: 1024 * 1024 * 100,
      type: Number
    },
    format: {
      default: () => {
        return ['jpg', 'jpeg', 'png', 'mp3', 'mp4', 'mav', 'mv']
      },
      type: Array
    },
    imageMaxSize: {
      default: -1,
      type: Number
    },
    audioMaxSize: {
      default: -1,
      type: Number
    },
    audioMaxDuration: {
      default: -1,
      type: Number
    },
    videoMaxSize: {
      default: -1,
      type: Number
    },
    fileType: {
      default: -1
    },
    isDisabled: {
      type: Boolean,
      default: false
    }

  },
  data () {
    return {
      showRecorder: false,
      uploadFile: [],
      uploadUrl: '',
      headers: {},
      data: {},
      fileUrl: new Map(),
      showVideoModal: false,
      showAudioModal: false,
      errorCode: 0
    }
  },
  computed: {},

  watch: {
    defaultFileList () {
      if (this.defaultFileList) { this.init() }
    }

  },
  mounted () {
    this.init()
  },
  methods: {

    record () {
      this.showRecorder = true
      this.$refs.rec.init()
    },
    getFileList () {
      return this.uploadFile
    },
    init () {
      this.uploadFile = this.defaultFileList
    },
    clear () {
      this.uploadFile = []
    },
    handleView (item) {
      if (item.type === 3) {
        this.showVideoModal = true
        this.$refs.videoRef.play()
      } else if (item.type === 2) {
        this.showAudioModal = true
        this.$refs.audioRef.play()
      } else {
        const image = new Image()
        image.src = item.url
        const viewer = new Viewer(image, {
          zIndex: 99999999,
          hidden () {
            viewer.destroy()
          }
        })
        viewer.show()
      }
    },
    handleUploadSuccess (res, file, fileList) {
      console.log('handleUploadSuccess', file.name)
      if (this.uploadFile.length < this.maxLength) { this.uploadFile.push({ type: this.fileType, url: this.fileUrl.get(file.name) }) }
    },
    handleUploadError (error, file, fileList) {
      console.log('handleUploadError', file.name, error)
      this.$Message.error({
        content: `【${error}】，上传失败`,
        duration: 2
      })
    },
    handleRemove (index, item) {
      this.uploadFile.splice(index, 1)
      this.$Message.success('移除成功')
    },
    handleMaxSize (file) {
      this.$Message.error({
        content: `【${file.name}】文件超过【${this.bateChange(this.maxSize)}】大小，请重新上传`,
        duration: 3
      })
    },
    handleFormatError (file) {
      this.$Message.error({
        content: `【${file.name}】文件格式不支持，当前只支持【${this.format}】格式，请重新上传`,
        duration: 3
      })
    },
    handleBeforeUpload (file) {
      const param = { type: this.type, contentType: file.type, fileName: file.name }

      if (this.uploadFile.length > this.maxLength) { return false }

      // 获取文件类型
      const formatName = file.type.split('/')[0]
      if (formatName === 'video') {
        this.fileType = 3
        if (this.videoMaxSize > 0 && this.videoMaxSize < (file.size / 1024)) {
          this.$Message.error({
            content: `请上传${this.bateChange(this.videoMaxSize * 1024)}以内的视频`,
            duration: 3
          })
          return false
        }
      } else if (formatName === 'audio') {
        this.fileType = 2
        if (this.audioMaxSize > 0 && this.audioMaxSize < (file.size / 1024)) {
          this.$Message.error({
            content: `请上传${this.bateChange(this.audioMaxSize * 1024)}以内的音频`,
            duration: 3
          })
          return false
        }
      } else if (formatName === 'image') {
        this.fileType = 1
        if (this.imageMaxSize > 0 && this.imageMaxSize < (file.size / 1024)) {
          this.$Message.error({
            content: `请上传${this.bateChange(this.imageMaxSize * 1024)}以内的图片`,
            duration: 3
          })
          return false
        }
      } else {
        this.$Message.error({
          content: '文件组件只支持图片、音频、视频',
          duration: 2
        })
        return false
      }
      return this.sign(param)
    },
    sign (param) {
      return new Promise((resolve, reject) => {
        this.$serverApi.getSign(param).then((res) => {
          if (res.success) {
            this.fileUrl.set(param.fileName, res.data.url)
            delete res.data.url
            this.data = res.data
            resolve(true)
          } else {
            this.$Message.error({
              content: res.message,
              duration: 3
            })
            reject(false)
          }
        }).catch((e) => {
          this.$Message.error({
            content: '文件获取签名失败，请联系管理人员',
            duration: 3
          })
          reject(false)
        })
      })
    },
    getDuration (file) {
      let audioDuration = 0
      const url = URL.createObjectURL(file)
      const audioElement = new Audio(url)
      return new Promise((resolve, reject) => {
        audioElement.onloadedmetadata = () => {
          audioDuration = Number.parseInt(audioElement.duration)
          resolve(audioDuration)
        }
      })
    },
    bateChange (limit) {
      let size = ''
      if (limit < 0.1 * 1024) { // 小于0.1KB，则转化成B
        size = `${limit.toFixed(2)}B`
      } else if (limit < 0.1 * 1024 * 1024) { // 小于0.1MB，则转化成KB
        size = `${(limit / 1024).toFixed(2)}KB`
      } else if (limit < 0.1 * 1024 * 1024 * 1024) { // 小于0.1GB，则转化成MB
        size = `${(limit / (1024 * 1024)).toFixed(2)}MB`
      } else { // 其他转化成GB
        size = `${(limit / (1024 * 1024 * 1024)).toFixed(2)}GB`
      }
      const sizeStr = `${size}` // 转成字符串
      const index = sizeStr.indexOf('.') // 获取小数点处的索引
      const dou = sizeStr.substr(index + 1, 2) // 获取小数点后两位的值
      if (dou === '00') { // 判断后两位是否为00，如果是则删除00
        return sizeStr.substring(0, index) + sizeStr.substr(index + 3, 2)
      }
      return size
    }

  }

}
</script>

<style scoped lang="less">
.demo-upload-list {
        text-align: center;
        border: 1px solid transparent;
        border-radius: 4px;
        overflow: hidden;
        background: #fff;
        position: relative;
        /*box-shadow: 0 1px 1px rgba(0, 0, 0, .2);*/
        display: flex;
        justify-content: center;
        align-items: center;
    }

    .clear-margin {
        margin: 0;
    }

    .demo-upload-list img {
        width: 100%;
        height: 100%;
        /*object-fit: contain;*/
    }

    .demo-upload-list video {
        width: 100%;
        height: 100%;
        object-fit: contain;
    }

    .demo-upload-list audio {
        width: 100%;
        height: 100%;
        object-fit: contain;
    }

    .demo-upload-list-cover {
        display: none;
        position: absolute;
        top: 0px;
        bottom: 0;
        left: 0;
        right: 0;
        background: rgba(0, 0, 0, .6);
    }

    .demo-upload-list:hover .demo-upload-list-cover {
        display: block;
    }

    .demo-upload-list-cover i {
        color: #fff;
        font-size: 20px;
        cursor: pointer;
        margin: 0 2px;
    }

    ul {
        padding: 0;
        display: flex;
        flex-wrap: wrap;
        justify-content: flex-start;

        width: 100%;
        height: 100%;
    }

    li {
        list-style: none;
        text-align: center;
        border-radius: 5px;
        height: 40%;
        /*border: 1px solid #B2B2B2;*/
    }

    /deep/ .ivu-upload-drag {
        border: 0px;
    }

    .file-list {
        display: flex;
        flex-direction: row;
        align-items: center;
    }

    .file-list_upload {
        display: flex;
        align-items: center;
        justify-content: center;
    }
</style>
